package de.zainodis.authorlist.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import de.zainodis.commons.component.Component;
import de.zainodis.commons.component.IEntity;

/**
 * Maps author names to their creations.
 * 
 * @author fzarrai
 * 
 */
public class AuthorLibraryComponent extends Component {

   /** Maps authors to their works/creations */
   private Map<String, Collection<AuthorsCreation>> authorsToCreations = new HashMap<String, Collection<AuthorsCreation>>();

   public AuthorLibraryComponent(IEntity owner) {
	 super(owner);
   }

   /**
    * Maps the given creation to each of it's authors.
    * 
    * @param creation
    *           the creation to add.
    */
   public void addMapping(AuthorsCreation creation) {
	 if (creation == null) {
	    return;
	 }

	 Collection<String> authors = creation.getAuthors();

	 if (authors == null) {
	    return;
	 }

	 for (String author : authors) {
	    if (author != null) {
		  // The author already exists, add this creation to his/her works
		  Collection<AuthorsCreation> creations = authorsToCreations.get(author);
		  if (creations == null) {
			creations = new ArrayList<AuthorsCreation>();
		  }
		  if (!creations.contains(creation)) {
			// Add the creation to the authors works
			creations.add(creation);
			// And update the author's work track record
			authorsToCreations.put(author, creations);
		  }
	    }
	 }
   }

   public void addMappings(Collection<? extends AuthorsCreation> items) {
	 if (items == null) {
	    return;
	 }
	 for (AuthorsCreation item : items) {
	    addMapping(item);
	 }
   }

   public void addAuthors(Collection<String> authors) {
	 if (authors == null) {
	    return;
	 }

	 for (String author : authors) {
	    if (!authorsToCreations.containsKey(author)) {
		  authorsToCreations.put(author, null);
	    }
	 }
   }

   public Collection<String> getAuthors() {
	 return authorsToCreations.keySet();
   }

   /**
    * @param author
    *           the author whose creations should be returned.
    * @return a {@link Collection} of {@link AuthorsCreation}s for the given
    *         author; an empty collection if there are no results.
    */
   public Collection<AuthorsCreation> get(String author) {
	 Collection<AuthorsCreation> result = null;

	 if (authorsToCreations.containsKey(author)) {
	    result = authorsToCreations.get(author);
	 }

	 if (result == null) {
	    result = new ArrayList<AuthorsCreation>();
	 }

	 return result;
   }

   /**
    * @return true, of this library has at least one author; false otherwise.
    */
   public boolean hasAuthors() {
	 return authorsToCreations.size() > 0;
   }

   public int countAuthors() {
	 return authorsToCreations.size();
   }

   public void clear() {
	 authorsToCreations.clear();
   }
}
